const express = require('express');
const multer = require('multer');
const sharp = require('sharp');
const path = require('path');
const fs = require('fs');
const { PDFDocument } = require('pdf-lib');
const { Document, Packer, Paragraph } = require('docx');
const PDFParser = require('pdf2json');
const mammoth = require('mammoth');
const libre = require('libreoffice-convert');
const { promisify } = require('util');
const libreConvert = promisify(libre.convert);

const app = express();
const port = 3000;

// 配置上传目录
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir, { recursive: true });
}

// 配置文件存储
const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, uploadDir);
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + path.extname(file.originalname));
    }
});

const upload = multer({ 
    storage: storage,
    limits: {
        fileSize: 10 * 1024 * 1024 // 限制文件大小为10MB
    },
    fileFilter: (req, file, cb) => {
        // 允许的文件类型
        const allowedTypes = [
            'image/jpeg', 
            'image/png', 
            'image/gif', 
            'image/webp',
            'application/pdf', 
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'text/plain'
        ];
        if (allowedTypes.includes(file.mimetype)) {
            cb(null, true);
        } else {
            cb(new Error('不支持的文件类型：' + file.mimetype));
        }
    }
});

// 静态文件服务
app.use(express.static(path.join(__dirname, '../frontend')));
app.use('/uploads', express.static(uploadDir));

// 错误处理中间件
app.use((err, req, res, next) => {
    console.error('服务器错误:', err);
    res.status(500).json({ 
        success: false, 
        message: '服务器错误: ' + err.message 
    });
});

// 文件上传接口
app.post('/api/upload', upload.single('file'), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ success: false, message: '未上传文件' });
    }
    res.json({
        success: true,
        fileId: req.file.filename,
        url: `/uploads/${req.file.filename}`
    });
});

// 文件转换函数
async function convertFile(inputPath, outputPath, sourceFormat, targetFormat) {
    try {
        console.log(`开始转换: ${sourceFormat} -> ${targetFormat}`);
        console.log(`输入文件: ${inputPath}`);
        console.log(`输出文件: ${outputPath}`);

        // 获取文件扩展名
        const sourceExt = sourceFormat.toLowerCase();
        const targetExt = targetFormat.toLowerCase();

        // 验证文件是否存在
        if (!fs.existsSync(inputPath)) {
            throw new Error('源文件不存在');
        }

        // 文本文件之间的转换
        if (['txt', 'doc', 'docx'].includes(sourceExt) && ['txt', 'doc', 'docx'].includes(targetExt)) {
            console.log('执行文本文件转换');
            if (sourceExt === 'txt') {
                const text = fs.readFileSync(inputPath, 'utf-8');
                if (targetExt === 'doc' || targetExt === 'docx') {
                    const doc = new Document({
                        title: "Converted Document",
                        description: "Document converted from TXT",
                        sections: [{
                            properties: {},
                            children: [new Paragraph(text)]
                        }]
                    });
                    const buffer = await Packer.toBuffer(doc);
                    fs.writeFileSync(outputPath, buffer);
                }
            } else if (sourceExt === 'doc' || sourceExt === 'docx') {
                const result = await mammoth.extractRawText({ path: inputPath });
                if (targetExt === 'txt') {
                    fs.writeFileSync(outputPath, result.value);
                } else if (targetExt === 'doc' || targetExt === 'docx') {
                    const doc = new Document({
                        title: "Converted Document",
                        description: "Document converted from " + sourceExt.toUpperCase(),
                        sections: [{
                            properties: {},
                            children: [new Paragraph(result.value)]
                        }]
                    });
                    const buffer = await Packer.toBuffer(doc);
                    fs.writeFileSync(outputPath, buffer);
                }
            }
        }
        // PDF相关转换
        else if (sourceExt === 'pdf') {
            console.log('执行PDF转换');
            if (targetExt === 'txt') {
                return new Promise((resolve, reject) => {
                    const pdfParser = new PDFParser();
                    pdfParser.on('pdfParser_dataReady', (pdfData) => {
                        try {
                            const text = pdfData.Pages.map(page => 
                                page.Texts.map(text => decodeURIComponent(text.R[0].T)).join(' ')
                            ).join('\n');
                            fs.writeFileSync(outputPath, text);
                            resolve();
                        } catch (error) {
                            reject(error);
                        }
                    });
                    pdfParser.on('pdfParser_dataError', (err) => {
                        reject(err);
                    });
                    pdfParser.loadPDF(inputPath);
                });
            }
        }
        // 转换为PDF
        else if (targetExt === 'pdf') {
            console.log('执行转换为PDF');
            if (sourceExt === 'txt') {
                const text = fs.readFileSync(inputPath, 'utf-8');
                const pdfDoc = await PDFDocument.create();
                const page = pdfDoc.addPage();
                page.drawText(text, { x: 50, y: page.getHeight() - 50 });
                const pdfBytes = await pdfDoc.save();
                fs.writeFileSync(outputPath, pdfBytes);
            } else if (sourceExt === 'doc' || sourceExt === 'docx') {
                const result = await mammoth.extractRawText({ path: inputPath });
                const pdfDoc = await PDFDocument.create();
                const page = pdfDoc.addPage();
                page.drawText(result.value, { x: 50, y: page.getHeight() - 50 });
                const pdfBytes = await pdfDoc.save();
                fs.writeFileSync(outputPath, pdfBytes);
            }
        }
        else {
            throw new Error(`不支持从 ${sourceFormat} 转换到 ${targetFormat}`);
        }

        // 验证转换后的文件是否存在
        if (!fs.existsSync(outputPath)) {
            throw new Error('转换后的文件未生成');
        }

        console.log('转换完成');
        return true;
    } catch (error) {
        console.error('转换错误:', error);
        throw error;
    }
}

// 修改文件转换接口
app.post('/api/convert', upload.single('file'), async (req, res) => {
    try {
        console.log('收到转换请求');
        
        if (!req.file) {
            return res.status(400).json({ 
                success: false, 
                message: '未上传文件' 
            });
        }

        const { targetFormat } = req.body;
        if (!targetFormat) {
            return res.status(400).json({ 
                success: false, 
                message: '未指定目标格式' 
            });
        }

        const inputFile = req.file.path;
        const sourceFormat = path.extname(req.file.originalname).slice(1).toLowerCase();
        const outputFile = path.join(uploadDir, `converted-${Date.now()}.${targetFormat}`);

        console.log(`源文件: ${inputFile}`);
        console.log(`源格式: ${sourceFormat}`);
        console.log(`目标格式: ${targetFormat}`);
        console.log(`输出文件: ${outputFile}`);

        // 验证转换格式
        const supportedFormats = ['txt', 'doc', 'docx', 'pdf'];
        if (!supportedFormats.includes(sourceFormat) || !supportedFormats.includes(targetFormat)) {
            return res.status(400).json({ 
                success: false, 
                message: `不支持的转换格式: ${sourceFormat} -> ${targetFormat}` 
            });
        }

        await convertFile(inputFile, outputFile, sourceFormat, targetFormat);

        res.json({
            success: true,
            downloadUrl: `/uploads/${path.basename(outputFile)}`
        });
    } catch (error) {
        console.error('转换错误:', error);
        res.status(500).json({ 
            success: false, 
            message: '文件转换失败: ' + error.message 
        });
    }
});

// 图片压缩接口
app.post('/api/image/compress', upload.single('file'), async (req, res) => {
    try {
        const { quality } = req.body;
        const inputFile = req.file.path;
        const outputFile = path.join(uploadDir, `compressed-${Date.now()}.jpg`);

        await sharp(inputFile)
            .jpeg({ quality: parseInt(quality) })
            .toFile(outputFile);

        res.json({
            success: true,
            previewUrl: `/uploads/${path.basename(outputFile)}`,
            downloadUrl: `/uploads/${path.basename(outputFile)}`
        });
    } catch (error) {
        console.error('压缩错误:', error);
        res.status(500).json({ success: false, message: '图片压缩失败' });
    }
});

// 图片裁剪接口
app.post('/api/image/crop', upload.single('file'), async (req, res) => {
    try {
        const { x, y, width, height } = req.body;
        const inputFile = req.file.path;
        const outputFile = path.join(uploadDir, `cropped-${Date.now()}.jpg`);

        // 验证参数
        if (!x || !y || !width || !height) {
            throw new Error('缺少裁剪参数');
        }

        // 获取原图尺寸
        const metadata = await sharp(inputFile).metadata();
        
        // 验证裁剪区域是否有效
        const cropX = Math.max(0, parseInt(x));
        const cropY = Math.max(0, parseInt(y));
        const cropWidth = Math.min(metadata.width - cropX, parseInt(width));
        const cropHeight = Math.min(metadata.height - cropY, parseInt(height));

        if (cropWidth <= 0 || cropHeight <= 0) {
            throw new Error('无效的裁剪区域');
        }

        // 执行裁剪
        await sharp(inputFile)
            .extract({ 
                left: cropX, 
                top: cropY, 
                width: cropWidth, 
                height: cropHeight 
            })
            .toFile(outputFile);

        res.json({
            success: true,
            previewUrl: `/uploads/${path.basename(outputFile)}`,
            downloadUrl: `/uploads/${path.basename(outputFile)}`
        });
    } catch (error) {
        console.error('裁剪错误:', error);
        res.status(500).json({ success: false, message: '图片裁剪失败: ' + error.message });
    }
});

// 图片水印接口
app.post('/api/image/watermark', upload.single('file'), async (req, res) => {
    try {
        const { text, x, y, fontSize = 40, color = 'rgba(255,255,255,0.5)' } = req.body;
        const inputFile = req.file.path;
        const outputFile = path.join(uploadDir, `watermarked-${Date.now()}.jpg`);

        // 验证参数
        if (!text) {
            throw new Error('缺少水印文本');
        }

        // 创建SVG水印
        const svgText = `
            <svg width="500" height="100">
                <text 
                    x="0" 
                    y="50" 
                    font-family="Arial" 
                    font-size="${fontSize}" 
                    fill="${color}"
                    transform="rotate(-30, 50, 50)"
                >
                    ${text}
                </text>
            </svg>
        `;

        const svgBuffer = Buffer.from(svgText);

        // 获取原图尺寸
        const metadata = await sharp(inputFile).metadata();
        
        // 计算水印位置
        const watermarkX = x ? parseInt(x) : Math.floor(metadata.width / 4);
        const watermarkY = y ? parseInt(y) : Math.floor(metadata.height / 4);

        // 添加水印
        await sharp(inputFile)
            .composite([{
                input: svgBuffer,
                top: watermarkY,
                left: watermarkX
            }])
            .toFile(outputFile);

        res.json({
            success: true,
            previewUrl: `/uploads/${path.basename(outputFile)}`,
            downloadUrl: `/uploads/${path.basename(outputFile)}`
        });
    } catch (error) {
        console.error('水印错误:', error);
        res.status(500).json({ success: false, message: '添加水印失败: ' + error.message });
    }
});

// 图片格式转换接口
app.post('/api/image/convert', upload.single('file'), async (req, res) => {
    try {
        const { format } = req.body;
        const inputFile = req.file.path;
        const outputFile = path.join(uploadDir, `converted-${Date.now()}.${format}`);

        // 验证格式
        const supportedFormats = ['jpeg', 'jpg', 'png', 'webp', 'gif'];
        if (!format || !supportedFormats.includes(format.toLowerCase())) {
            throw new Error('不支持的图片格式');
        }

        // 转换格式
        await sharp(inputFile)
            .toFormat(format.toLowerCase())
            .toFile(outputFile);

        res.json({
            success: true,
            previewUrl: `/uploads/${path.basename(outputFile)}`,
            downloadUrl: `/uploads/${path.basename(outputFile)}`
        });
    } catch (error) {
        console.error('格式转换错误:', error);
        res.status(500).json({ success: false, message: '图片格式转换失败: ' + error.message });
    }
});

// 文件下载接口
app.get('/uploads/:filename', (req, res) => {
    const file = path.join(uploadDir, req.params.filename);
    if (fs.existsSync(file)) {
        res.download(file);
    } else {
        res.status(404).send('文件不存在');
    }
});

// 启动服务器
app.listen(port, () => {
    console.log(`服务器运行在 http://localhost:${port}`);
}); 